package db

import (
	"gorm.io/gorm"
	"time"
	"zong-microservice/app/models"
	"zong-microservice/pkg/config"
	"zong-microservice/pkg/database"
	"zong-microservice/pkg/helper"
	"zong-microservice/pkg/logger"
	"zong-microservice/pkg/password"
)

// InitDB 初始化数据库和 ORM
func InitDB() {
	// 数据库连接池
	db := getDB(getConnData())
	// 命令行打印数据库请求的信息
	sqlDB, _ := db.DB()
	// 设置最大连接数
	sqlDB.SetMaxOpenConns(helper.StringToInt(config.Get("database", "max_open_connections")))
	// 设置最大空闲连接数
	sqlDB.SetMaxIdleConns(helper.StringToInt(config.Get("database", "max_idle_connections")))
	// 设置每个链接的过期时间
	sqlDB.SetConnMaxLifetime(time.Duration(helper.StringToInt(config.Get("database", "max_life_seconds"))) * time.Second)

	// 创建和维护数据表结构
	migration(db)
}

// getDB 获取数据库连接池
func getDB(connData database.ConnData) *gorm.DB {
	switch connData.Connection {
	case "mysql":
		// 建立数据库连接池
		return database.MysqlConnector(connData)
	case "postgres":
	case "sqlite":
	case "sqlserver":
	default:
		return database.MysqlConnector(connData)
	}
	return database.DB
}

// getConnData 获取数据库默认配置
func getConnData() database.ConnData {
	return database.ConnData{
		Connection: config.Get("database", "connection"),
		Host:       config.Get("database", "host"),
		Port:       config.Get("database", "port"),
		Database:   config.Get("database", "database"),
		Username:   config.Get("database", "username"),
		Password:   config.Get("database", "password"),
		Charset:    config.Get("database", "charset"),
	}
}

func migration(db *gorm.DB) {
	// 自动迁移
	err := db.AutoMigrate(
		&models.User{},
		&models.File{},
		&models.UserFile{},
	)
	logger.LogError(err)
	// 初始化超级管理员
	// 如果检索到0行，且传入接收检索结果的不是一个Slice类型的变量（这时候肯定是一个Struct类型的变量），会抛出 ErrRecordNotFound 错误
	if err := db.Where("username = ?", "sysadmin").First(&models.User{}).Error; err != nil || err == gorm.ErrRecordNotFound {
		sysAdmin := models.User{
			Username: "sysadmin",
			Name:     "超级管理员",
			Phone:    "12345678910",
			Password: password.Hash(config.Get("app", "name")),
			Avatar:   "",
		}
		err = sysAdmin.Create()
		logger.LogError(err)
	}
}
